﻿using System;
using System.Configuration;
using System.Text;
using System.Windows;
using System.Net;
using System.Net.Sockets;
using System.Windows.Controls;
using System.Threading;
using System.Windows.Threading;
using System.Collections.Generic;
using ServerApplication.Communication;
using System.Linq;
using ServerApplication.ConfigFile;


namespace ServerApplication
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        SocketPermission permission;
        Socket sListener;
        IPEndPoint ipEndPoint;
        Socket handler;



        ConfigFileObject configFileObject;

        ConfigFileObject ConfigFileObject
        {
            get { return configFileObject; }
            set { configFileObject = value; }
        }

        PeerManager.PeerManager manager;
        private string ipv4;
        private int port;

        Thread mListeningThread;
        public MainWindow()
        {
            this.configFileObject = new ConfigFileObject();
            this.manager = new PeerManager.PeerManager();
            CommunicationUtil.mPeerManager = this.manager;
            this.Loaded += MainWindow_Loaded;
            InitializeComponent();
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(2000);
            timer.Tick += RefreshDataGrid;
            timer.Start();
        }

        private void RefreshDataGrid(object sender, EventArgs e)
        {
            allPeers.Items.Refresh();
            PeerStatus.Items.Refresh();
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>   Event handler. Called by MainWindow for loaded events. Binds the datagrid on load to the data source </summary>
        ///
        /// <remarks>   Adrian, 11/11/2015. </remarks>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Routed event information. </param>
        ///-------------------------------------------------------------------------------------------------

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this.allPeers.ItemsSource = manager.mAllPeers.Values;
            this.PeerStatus.ItemsSource = manager.mAllStatus.Values;
        }

        private void tbAux_SelectionChanged(object sender, RoutedEventArgs e)
        {
            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate()
            {
                
            });
        }

        private void Start_Click(object sender, RoutedEventArgs e)
        {
            mListeningThread = new Thread(() => { Communication.CommunicationUtil.ListenOnNetwork(); });
            mListeningThread.Start();
            serverOnline.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green);
        }

        private void StartPeers_Click(object sender, RoutedEventArgs e)
        {

        }

        private void StartAllPeers_Click(object sender, RoutedEventArgs e)
        {
            Thread tempThread = new Thread( () => 
            {
                try
                {
                    Communication.CommunicationUtil.SendToPeers(new List<PeerManager.Peer>(manager.mAllPeers.Values), UtilCommunication.CommandsToSendList.START_PROCESS);
                    MessageBox.Show("All involved peers have been messaged succesfully");
                }
                catch(Exception ex)
                {
                    MessageBox.Show("Job Aborted error occured "+ ex.StackTrace);
                }
            });
            tempThread.Start();
        }

        private void StartSelectedPeers_Click(object sender, RoutedEventArgs e)
        {
            List<PeerManager.Peer> selectedPeers = allPeers.SelectedItems.Cast<PeerManager.Peer>().ToList();
            Thread tempThread = new Thread(() => 
                {
                    try
                    {
                        Communication.CommunicationUtil.SendToPeers(selectedPeers, UtilCommunication.CommandsToSendList.START_PROCESS);
                        MessageBox.Show("All involved peers have been messaged succesfully");
                    }
                    catch(Exception ex)
                    {
                        MessageBox.Show("Job Aborted error occured "+ ex.StackTrace);
                    }
                });

            tempThread.Start();
            MonitorPeers();
        }

        private void StopSelectedPeers_Click(object sender, RoutedEventArgs e)
        {
            List<PeerManager.Peer> selectedPeers = allPeers.SelectedItems.Cast<PeerManager.Peer>().ToList();
            Thread tempThread = new Thread(() =>
            {
                try
                {
                    Communication.CommunicationUtil.SendToPeers(selectedPeers, UtilCommunication.CommandsToSendList.TERMINATE_PROCESS);
                    MessageBox.Show("All involved peers have been messaged succesfully");
                }
                catch(Exception ex)
                {
                    MessageBox.Show("Job Aborted error occured " + ex.StackTrace);
                }
            });


            tempThread.Start();
            MonitorPeers();
        }

        private void StopAllPeers_Click(object sender, RoutedEventArgs e)
        {
            Thread tempThread = new Thread(() =>
            {
                Communication.CommunicationUtil.SendToPeers(new List<PeerManager.Peer>(manager.mAllPeers.Values), UtilCommunication.CommandsToSendList.TERMINATE_PROCESS);
                MessageBox.Show("All involved peers have been messaged succesfully");
            });

            tempThread.Start();
        }


        private void Send_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //Communication.CommunicationUtil.SendData(handler, tbMsgToSend.Text);
                //Close_Button.IsEnabled = true;
            }
            catch (Exception exc) { MessageBox.Show(exc.ToString()); }
        }

      

        private void Close_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (sListener.Connected)
                {
                    sListener.Shutdown(SocketShutdown.Receive);
                    sListener.Close();
                }

                //Close_Button.IsEnabled = false;
            }
            catch (Exception exc) { MessageBox.Show(exc.ToString()); }
        }

        private void VerifyLocation_Click(object sender, RoutedEventArgs e)
        {
            
        }

        private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {

        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary>   Event handler. Called by Button_Click for 2 events. Config File Saver</summary>
        ///
        /// <remarks>   Adrian, 11/11/2015. </remarks>
        ///
        /// <param name="sender">   Source of the event. </param>
        /// <param name="e">        Routed event information. </param>
        ///-------------------------------------------------------------------------------------------------

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            configFileObject = new ConfigFileObject();
            configFileObject.AmountPeers = Convert.ToInt32(this.amountPeers.Text);
            configFileObject.gatekeeperIp = this.gatekeeperIp.Text;
            configFileObject.pathConfigFile = this.pathConfigFile.Text;
            configFileObject.pathNumber = Convert.ToInt32(this.pathNumber.Text);
            float.TryParse(this.intervalForBenchmark.Text, out configFileObject.intervalForBenchmark);
            float.TryParse(this.timeAfterCommAttempt.Text, out configFileObject.timeAfterCommAttempt);
            float.TryParse(this.timeSleepAfterFailedAttempt.Text, out configFileObject.timeSleepAfterFailedAttempt);
            configFileObject.useNetwork = Convert.ToInt32(this.useNetwork.Text);
            configFileObject.socketNumber = Convert.ToInt32(this.socketNumber.Text);
            configFileObject.peerName = this.peerName.Text;
            configFileObject.sceneType = Convert.ToInt32(this.sceneType.Text);
            configFileObject.windowSize = Convert.ToInt32(this.windowSize.Text);
            configFileObject.amountThreads = Convert.ToInt32(this.mt.Text);
            configFileObject.useRandomPath = Convert.ToInt32(this.useRandomPath.Text);
            configFileObject.pathConfigFile = this.pathConfigFile.Text;

            //Thread currentThread = new Thread(() => configFileObject.SaveFile(manager, directroy.Text.Equals("") ? "Y:" : directroy.Text));
            configFileObject.SaveFile(manager, directroy.Text.Equals("") ? "" : directroy.Text);
            
        }

        private void MonitorPeers()
        {
            //monitoringBulb.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Green);
            //Thread currentThread = new Thread(() => UpdatesManager.UpdatesManager.GetUpdates(directroy.Text, manager));
            //currentThread.Start();
        }

        private void Start_Button_Copy_Click(object sender, RoutedEventArgs e)
        {

            HelperFunctions.StartGateKeeperProcess();
        }

        private void Button_Click_3(object sender, RoutedEventArgs e)
        {
            allPeers.Items.Refresh();
        }
        
    }
}
